#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <pthread.h>
#define MAX_BUF 1024
#define SERVER_PORT 8888
#define LISTEN_QUEUE 5
int clients[LISTEN_QUEUE] = {0}; //  存放客户端套接字的数组

// 处理客户端请求
void *handle_client(void *arg)
{
    sleep(1);
    int client_fd = *(int *)arg;
    char read_buf[MAX_BUF], send_buf[MAX_BUF];
    int read_size, i, ret;
    struct sockaddr_in client_addr;
    int addr_len = sizeof(client_addr);
    // 获取套接字的IP和端口
    ret = getsockname(client_fd, (struct sockaddr *)&client_addr, &addr_len);
    if (ret < 0)
    {
        perror("getsockname");
    }

    while (1)
    {
        memset(read_buf, 0, MAX_BUF);
        memset(send_buf, 0, MAX_BUF);
        read_size = recv(client_fd, read_buf, MAX_BUF, 0);
        if (read_size < 0)
        {
            perror("recv");
            break;
        }
        if (read_size == 0)
        {
            // 客户端断开连接
            printf("client disconnected\n");
            break;
        }
        printf("recv: %s\n", read_buf);

        // 拼装发送数据,将客户端IP和端口添加到数据包中
        sprintf(send_buf, "%s: %s", inet_ntoa(client_addr.sin_addr), read_buf);

        // 发送数据到所有客户端
        for (i = 0; i < LISTEN_QUEUE; i++)
        {
            if (clients[i] != 0 && clients[i] != client_fd)
            {
                send(clients[i], send_buf, strlen(send_buf), 0);
            }
        }
    }

    close(client_fd); // 关闭客户端套接字
    // 从数组中删除客户端
    for (i = 0; i < LISTEN_QUEUE; i++)
    {
        if (clients[i] == client_fd)
        {
            clients[i] = 0;
        }
    }

    pthread_exit(NULL); // 退出线程
}

int main()
{

    int server_fd, client_fd, i;
    struct sockaddr_in server_addr, client_addr;
    pthread_t tid;
    int ret; // 返回值

    // 清空客户端数组
    for (i = 0; i < LISTEN_QUEUE; i++)
    {
        clients[i] = 0;
    }

    // 创建套接字
    server_fd = socket(AF_INET, SOCK_STREAM, 0); // TCP
    if (server_fd < 0)
    {
        perror("socket");
        exit(1);
    }

    // 初始化server_addr
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY; // IP地址,接受所有ip地址

    // 绑定地址和端口
    ret = bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (ret < 0)
    {
        perror("bind");
        close(server_fd);
        exit(1);
    }

    // 设置监听数量
    ret = listen(server_fd, LISTEN_QUEUE);
    if (ret < 0)
    {
        perror("listen");
        close(server_fd);
        exit(1);
    }

    // 循环接收客户端连接请求
    while (1)
    {
        int addr_len = sizeof(client_addr);
        client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &addr_len);
        if (client_fd < 0)
        {
            perror("accept");
            continue;
        }
        printf("client connected,%d\n", client_fd);

        // 处理客户端请求
        // 创建子线程去处理客户端请求
        ret = pthread_create(&tid, NULL, (void *)handle_client, (void *)&client_fd);
        if (ret < 0)
        {
            perror("pthread_create");
            close(client_fd); // 关闭客户端套接字
            continue;
        }
        // 将客户端套接字加入到数组中
        for (i = 0; i < LISTEN_QUEUE; i++)
        {
            if (clients[i] == 0)
            {
                clients[i] = client_fd;
                break;
            }
        }
    }

    close(server_fd); // 关闭服务器套接字

    return 0;
}